/* 
 * Autores:
 *      Jonathan Lopez  11106
 *      Jorge Martínez  11237
 * 
 * Ultima revision: $Rev: 29 $
 *      Fecha: $Date: 2011-11-13 08:40:16 +0000 (Sun, 13 Nov 2011) $
 * 
 * Archivo: EnlaceDatosCSV.java
 */

package Datos.CSV;
import Servicios.*;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * Implementa la interfeca iEnlace para proveer el intercambio de datos
 * con los archivos .csv.
 * 
 * @author Jorge
 * @author Jonathan
 */
public class EnlaceDatosCSV implements iEnlace, ConstantesCSV {
    final private ArchivoCSV datos;
    private ArrayList<String> camposServicio = new ArrayList<String>();
    private ArrayList<String> valorCampos = new ArrayList<String>();
    
    final private Usuario usuarioActual;
    final private String categoriaServicio;
    final private String nombreServicio;

    /**
     * Constructor, inicializa todos los atributos.
     * 
     * @param datos Interface que provee acceso a los datos en el archivo .csv.
     * @param usuarioActual Usuario que se estara utilizando.
     * @param categoriaServicio Nombre de la categoria de servicio que
     * este enlace representa.
     * @param nombreServicio Nombre del servicio representado por este enlace.
     */
    public EnlaceDatosCSV(ArchivoCSV datos, Usuario usuarioActual,
            String categoriaServicio, String nombreServicio) {
        this.datos = datos;
        this.usuarioActual = usuarioActual;
        this.categoriaServicio = categoriaServicio;
        this.nombreServicio = nombreServicio;
        
        // Obtener los servicios proveidos en el archivo.
        /* Buscar por usuario */
        Integer[] lineas = datos.buscarLineas( nombreCampos[idxUsuario],
                this.usuarioActual.obtenerUsuario() );
        /* Buscar por categoria */
        lineas = datos.buscarLineas( nombreCampos[idxCategoria],
                this.categoriaServicio, lineas );
        /* Buscar por servicio */
        lineas = datos.buscarLineas( nombreCampos[idxNombreServicio],
                this.nombreServicio, lineas );
        
        if( lineas.length == 0 ){
            // Significa que este es un servicio nuevo. Si es parte de una
            // categoria "default" entonces se le agregan los respectivos
            // campos.
            HashMap<String, ArrayList<String>> categoriasDefault =
                    ProveedorDatosCSV.obtenerCategoriasDefault();
            
            if( !categoriasDefault.containsKey(categoriaServicio) )
                return;
            
            // Es una categoria "default"
            for (String campo : categoriasDefault.get(categoriaServicio)) {
                camposServicio.add(campo);
                valorCampos.add("");
            }
            
            return;
        }
        
        // Llenar los arreglos con null
        for (int i = 0; i < lineas.length; i++) {
            camposServicio.add(null);
            valorCampos.add(null);
        }
        
        // Llenar los arreglos con su respectivo valor del archivo
        for (Integer idxLinea : lineas) {
            String[] linea = datos.obtenerLinea(idxLinea);
            int cardinalidad = Integer.parseInt(linea[idxCardinalidad]);
            
            camposServicio.set( cardinalidad, linea[idxCampo] );
            valorCampos.set( cardinalidad, linea[idxValor] );
        }
    }
    
    @Override
    public boolean agregarCampo(String nombreCampo, int cardinalidad) {
        // Buscar que el campo no exista en el servicio
        if( camposServicio.contains( nombreCampo ) )
            return false;
        
        // Agregar el campo con un valor nulo
        if( cardinalidad < 0 || cardinalidad >= camposServicio.size() ){
            camposServicio.add( nombreCampo );
            valorCampos.add( "" );
        }else{
            camposServicio.add( cardinalidad, nombreCampo );
            valorCampos.add( cardinalidad, "" );
        }
        return true;
    }

    @Override
    public boolean cambiarCampo(String nombreCampo, String valorCampo) {
        // Buscar el campo en los servicios
        if( !camposServicio.contains(nombreCampo) )
            return false;
        
        if( valorCampo == null ){
            // Eliminar el campo
            int indice = camposServicio.indexOf(nombreCampo);
            
            camposServicio.remove(indice);
            valorCampos.remove(indice);
        } else {
            // Cambiar el valor del campo
            int indice = camposServicio.indexOf( nombreCampo );
            valorCampos.set(indice, valorCampo);
        }
        return true;
    }

    @Override
    public boolean cambiarCardinalidadCampo(String nombreCampo, int cardinalidad) {
        // Buscar el indice del campo
        if( !camposServicio.contains(nombreCampo) )
            return false;
        
        int indice = camposServicio.indexOf(nombreCampo);
        
        // Remover los valores de los arreglos
        camposServicio.remove(indice);
        String valor = valorCampos.remove(indice);
        
        // Insertar los valores en la nueva cardinalidad
        camposServicio.add(cardinalidad, nombreCampo);
        valorCampos.add(cardinalidad, valor);
        return true;
    }

    @Override
    public String obtenerCampo(String nombreCampo) {
        // Buscar el campo
        if( !camposServicio.contains(nombreCampo) )
            return null;
        
        int indice = camposServicio.indexOf(nombreCampo);
        return valorCampos.get(indice);
    }

    @Override
    public String obtenerCategoria() {
        return categoriaServicio;
    }

    @Override
    public String obtenerNombreServicio() {
        return nombreServicio;
    }

    @Override
    public boolean realizarCambios() {
        // Validar los arreglos de datos
        if( camposServicio.size() != valorCampos.size() )
            return false;
        
        // Obtener los servicios proveidos en el archivo.
        /* Buscar por usuario */
        Integer[] lineas = datos.buscarLineas( nombreCampos[idxUsuario],
                this.usuarioActual.obtenerUsuario() );
        /* Buscar por categoria */
        lineas = datos.buscarLineas( nombreCampos[idxCategoria],
                this.categoriaServicio, lineas );
        /* Buscar por servicio */
        lineas = datos.buscarLineas( nombreCampos[idxNombreServicio],
                this.nombreServicio, lineas );
        
        // Borrar las lineas del archivo
        datos.eliminarLineas(lineas);
        
        // Agregar los campos
        int cantidadCampos = camposServicio.size();
        for (int i = 0; i < cantidadCampos; i++) {
            // Validar el campo
            if( camposServicio.get(i).isEmpty() )
                continue;
            
            String[] linea = new String[nombreCampos.length];
            linea[idxUsuario] = usuarioActual.obtenerUsuario();
            linea[idxCategoria] = categoriaServicio;
            linea[idxNombreServicio] = nombreServicio;
            linea[idxCampo] = camposServicio.get(i);
            linea[idxValor] = valorCampos.get(i);
            linea[idxCardinalidad] = Integer.toString(i);
            datos.agregarLinea(linea);
        }
        datos.guardarCambios();
        
        return true;
    }

    @Override
    public String[] obtenerNombreCampos() {
        return camposServicio.toArray( new String[0] );
    }
    
    
}
